//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V1.0.1
/********************************************************
    说明：
    1、GPIO端口时钟开启或关闭。
    2、GPIO引脚模式配置。
    3、GPIO引脚状态获取或设置。
    4、GPIO端口16个引脚状态获取或设置。
    5、位操作GPIO端口引脚(操作几个引脚的话很推荐此方法)。
    6、基于stm32f4xx标准库V1.9.0
**********************************************************/

#ifndef __GPIO_BSP_H__
#define __GPIO_BSP_H__

/*****************************************************/
#include "stm32f4xx.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
/*****************************************************/

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

/*GPIO端口枚举*/
typedef enum
{
    PortA = (uint32_t)GPIOA,//端口A
    PortB = (uint32_t)GPIOB,//端口B
    PortC = (uint32_t)GPIOC,//端口C
    PortD = (uint32_t)GPIOD,//端口D
    PortE = (uint32_t)GPIOE,//端口E
    PortF = (uint32_t)GPIOF,//端口F
    PortG = (uint32_t)GPIOG,//端口G
    PortH = (uint32_t)GPIOH,//端口H
    PortI = (uint32_t)GPIOI,//端口I
    PortJ = (uint32_t)GPIOJ,//端口J
    PortK = (uint32_t)GPIOK,//端口K
}WHT_GPIO_Port_enum;

/*GPIO引脚号枚举*/
typedef enum
{
    Pin0  = GPIO_Pin_0, //引脚0号
    Pin1  = GPIO_Pin_1, //引脚1号
    Pin2  = GPIO_Pin_2, //引脚2号
    Pin3  = GPIO_Pin_3, //引脚3号
    Pin4  = GPIO_Pin_4, //引脚4号
    Pin5  = GPIO_Pin_5, //引脚5号
    Pin6  = GPIO_Pin_6, //引脚6号
    Pin7  = GPIO_Pin_7, //引脚7号
    Pin8  = GPIO_Pin_8, //引脚8号
    Pin9  = GPIO_Pin_9, //引脚9号
    Pin10 = GPIO_Pin_10,//引脚10号
    Pin11 = GPIO_Pin_11,//引脚11号
    Pin12 = GPIO_Pin_12,//引脚12号
    Pin13 = GPIO_Pin_13,//引脚13号
    Pin14 = GPIO_Pin_14,//引脚14号
    Pin15 = GPIO_Pin_15,//引脚15号
    PinAll= GPIO_Pin_All,//所有引脚
}WHT_GPIO_Pin_enum;

/*GPIO寄存器偏移地址枚举*/
typedef enum
{
    GPIO_IDR_Offset_Address = 0x10,//输入寄存器偏移量
    GPIO_ODR_Offset_Address = 0x14,//输出寄存器偏移量
    GPIO_BRR_Offset_Address = 0x18,//置位寄存器偏移量
    GPIO_BSRR_Offset_Address= 0x20,//复位寄存器偏移量
}WHT_GPIO_Bit_Offset_Address_enum;

/*GPIO状态枚举*/
typedef enum
{
    Low = 0,      //低电平
    Hig = 1,      //高电平
    Bit_Reset = 0,//低电平
    Bit_Set   = 1,//高电平
}WHT_GPIO_State_enum;

/*GPIO工作模式枚举*/
typedef enum
{
    Mode_Ain,        //模拟输入
    Mode_In_FLOATING,//浮空输入
    Mode_IPD,        //下拉输入
    Mode_IPU,        //上拉输入
    Mode_Out_OD,     //开漏输出
    Mode_Out_PP,     //推挽输出
    Mode_OPD_PP,     //下拉推挽输出
    Mode_OPU_PP,     //上拉推挽输出
    Mode_AF_OD,      //开漏复用输出
    Mode_AF_PP,      //推挽复用输出
}WHT_GPIO_Mode_enum;

/*GPIO复用功能枚举*/
typedef enum
{
    AFIO_RTC_50Hz = GPIO_AF_RTC_50Hz,//RTC_50Hz (也是复位默认功能)
    AFIO_MCO      = GPIO_AF_MCO,     //主时钟输出1和主时钟输出2功能 (也是复位默认功能)
    AFIO_TAMPER   = GPIO_AF_TAMPER,  //篡改1和篡改2功能 (也是复位默认功能)
    AFIO_SWJ      = GPIO_AF_SWJ,     //SWD和JTAG功能 (也是复位默认功能)
    AFIO_Default  = GPIO_AF_TRACE,   //复位默认功能
    AFIO_TIM1     = GPIO_AF_TIM1,
    AFIO_TIM2     = GPIO_AF_TIM2,
    AFIO_TIM3     = GPIO_AF_TIM3,
    AFIO_TIM4     = GPIO_AF_TIM4,
    AFIO_TIM5     = GPIO_AF_TIM5,
    AFIO_TIM8     = GPIO_AF_TIM8,
    AFIO_TIM9     = GPIO_AF_TIM9,
    AFIO_TIM10    = GPIO_AF_TIM10,
    AFIO_TIM11    = GPIO_AF_TIM11,
    AFIO_I2C1     = GPIO_AF_I2C1,
    AFIO_I2C2     = GPIO_AF_I2C2,
    AFIO_I2C3     = GPIO_AF_I2C3,
    AFIO_SPI1     = GPIO_AF_SPI1,
    AFIO_SPI2     = GPIO_AF_SPI2,
    AFIO_SPI4     = GPIO_AF_SPI4,
    AFIO_SPI5     = GPIO_AF_SPI5,
    AFIO_SPI6     = GPIO_AF_SPI6,
    AFIO_SAI1     = GPIO_AF_SAI1,//for STM32F42xxx/43xxx devices     
    AFIO_SPI3     = GPIO_AF_SPI3,//SPI3/I2S3
    AFIO_I2S3ext  = GPIO_AF_I2S3ext,
    AFIO_USART1   = GPIO_AF_USART1,
    AFIO_USART2   = GPIO_AF_USART2,
    AFIO_USART3   = GPIO_AF_USART3,
    AFIO_UART4    = GPIO_AF_UART4,
    AFIO_UART5    = GPIO_AF_UART5,
    AFIO_USART6   = GPIO_AF_USART6,
    AFIO_UART7    = GPIO_AF_UART7,
    AFIO_UART8    = GPIO_AF_UART8,
    AFIO_CAN1     = GPIO_AF_CAN1,
    AFIO_CAN2     = GPIO_AF_CAN2,
    AFIO_TIM12    = GPIO_AF_TIM12,
    AFIO_TIM13    = GPIO_AF_TIM13,
    AFIO_TIM14    = GPIO_AF_TIM14,
    AFIO_OTG_FS   = GPIO_AF_OTG_FS,
    AFIO_OTG_HS   = GPIO_AF_OTG_HS,
    AFIO_Ethernet = GPIO_AF_ETH,
#if defined(STM32F40_41xxx) || defined(STM32F412xG) || defined(STM32F413_423xx)
    AFIO_FSMC     = GPIO_AF_FSMC,
#endif /* STM32F40_41xxx || STM32F412xG || STM32F413_423xx */
#if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx)
    AFIO_FMC      = GPIO_AF_FMC,      //for STM32F42xxx/43xxx devices
#endif /* STM32F427_437xx || STM32F429_439xx || STM32F446xx || STM32F469_479xx */
    AFIO_OTG_HS_FS= GPIO_AF_OTG_HS_FS,//OTG HS (configured in FS)
    AFIO_SDIO     = GPIO_AF_SDIO,
    AFIO_DCMI     = GPIO_AF_DCMI,
    AFIO_AF9_LTDC = GPIO_AF9_LTDC,
    AFIO_LTDC     = GPIO_AF_LTDC,     //for STM32F429xx/439xx devices
    AFIO_EVENTOUT = GPIO_AF_EVENTOUT,
}WHT_GPIO_AFIO_enum;

/*GPIO回调函数结构体*/
typedef struct
{
    void (*WHT_Set_Clock)(WHT_GPIO_Port_enum portx, FunctionalState state);                         //使能端口时钟
    void (*WHT_Set_Mode)(WHT_GPIO_Port_enum portx, uint16_t pinx, WHT_GPIO_Mode_enum mode);         //设置工作模式 pinx for WHT_GPIO_Pin_enum
    void (*WHT_Set_Pin)(WHT_GPIO_Port_enum portx, uint16_t pinx, WHT_GPIO_State_enum state);        //设置引脚状态 pinx for WHT_GPIO_Pin_enum
    WHT_GPIO_State_enum(*WHT_Get_Pin)(WHT_GPIO_Port_enum portx, WHT_GPIO_Pin_enum pinx);            //获取引脚状态
    uint16_t (*WHT_Get_Prot)(WHT_GPIO_Port_enum portx);                                             //获取一组引脚状态
    void (*WHT_Set_Prot)(WHT_GPIO_Port_enum portx, uint16_t port_value);                            //设置一组引脚状态
    void (*WHT_Set_AFIO)(WHT_GPIO_Port_enum portx, WHT_GPIO_Pin_enum pinx, WHT_GPIO_AFIO_enum AFIO);//设置引脚复用功能
    void (*WHT_Register_Bit_Output)(WHT_GPIO_Port_enum portx, WHT_GPIO_Pin_enum pinx, volatile uint32_t** output);//注册位操作
    void (*WHT_Register_Bit_Input)(WHT_GPIO_Port_enum portx, WHT_GPIO_Pin_enum pinx, volatile uint32_t** input);  //注册位操作
}WHT_GPIO_BSP_t;

/*全局常量*/
extern const WHT_GPIO_BSP_t WHT_GPIO_BSP;

#endif /*__GPIO_BSP_H__*/
